home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / tkern091.zip / SRC / STDIO.C < prev    next >
Text File  |  1994-03-17  |  8KB  |  528 lines

  1. /*
  2.  *  This file forms part of "TKERN" - "Troy's Kernel for Windows".
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This file is explicitly placed in the public domain. You may use it
  7.  *  it for any purpose you see fit, including, but not limited to,
  8.  *  incorperating it into a private, commercial, public domain,
  9.  *  shareware, freeware or free software work.
  10.  */
  11.  
  12. #include <windows.h>
  13.  
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <io.h>
  17. #include <stdarg.h>
  18. #include <stdlib.h>
  19. #include <memory.h>
  20.  
  21. int
  22. __formatter(    int    (*func)(void *a, char b),
  23.         void    *func_arg,
  24.         char    const *format,
  25.         va_list    arg);
  26.  
  27. #define    MAXFILES 20
  28. #define    BUFSIZ    2048
  29.  
  30. FILE    _iob[MAXFILES];
  31.  
  32.  
  33. static    int getmodes(char const *mode,
  34.             int *flags)
  35. {
  36.     int    plus = 0;
  37.     int    reading = 0;
  38.     int    writing = 0;
  39.     int    binary = 0;
  40.     int    appending = 0;
  41.     int    modes;
  42.  
  43.     *flags = 0;
  44.  
  45.     while (*mode)
  46.     {
  47.         switch(*mode++)
  48.         {
  49.         case 'w':
  50.             writing = 1;
  51.             break;
  52.  
  53.         case 'r':
  54.             reading = 1;
  55.             break;
  56.  
  57.         case 'a':
  58.             appending = 1;
  59.             break;
  60.  
  61.         case 'b':
  62.             binary = 1;
  63.             break;
  64.  
  65.         case 't':
  66.             binary = 0;
  67.             break;
  68.  
  69.         case '+':
  70.             plus = 1;
  71.             break;
  72.         }
  73.     }
  74.  
  75.     if (writing)
  76.     {
  77.         if (plus || reading)
  78.         {
  79.             *flags = __FL_READ | __FL_WRITE;
  80.             modes = O_RDWR | O_CREAT | O_TRUNC;
  81.         }
  82.         else
  83.         {
  84.             *flags = __FL_WRITE;
  85.             modes = O_WRONLY | O_CREAT | O_TRUNC;
  86.         }
  87.     }
  88.     else if (appending)
  89.     {
  90.         if (plus || reading)
  91.         {
  92.             *flags = __FL_READ | __FL_WRITE;
  93.             modes = O_RDWR | O_CREAT;
  94.         }
  95.         else
  96.         {
  97.             *flags = __FL_WRITE;
  98.             modes = O_WRONLY | O_CREAT;
  99.         }
  100.     }
  101.     else if (reading)
  102.     {
  103.         if (plus)
  104.         {
  105.             *flags = __FL_READ | __FL_WRITE;
  106.             modes = O_RDWR;
  107.         }
  108.         else
  109.         {
  110.             *flags = __FL_READ;
  111.             modes = O_RDONLY;
  112.         }
  113.     }
  114.     if (binary)
  115.         modes |= O_BINARY;
  116.     else
  117.         modes |= O_TEXT;
  118.  
  119.     return    modes;
  120. }
  121.  
  122. static    void    _flsbuf(FILE *fp)
  123. {
  124.     if (fp->flags & __FL_MODIFIED)
  125.     {
  126.         lseek(fp->fd, -fp->readsize, 1);
  127.         write(fp->fd, fp->buffer, fp->bufsize);
  128.         fp->flags &= ~__FL_MODIFIED;
  129.     }
  130. }
  131.  
  132. static    int    _filbuf(FILE *fp)
  133. {
  134.     _flsbuf(fp);
  135.     if (fp->flags & __FL_READ)
  136.         fp->bufsize = read(fp->fd, fp->buffer, BUFSIZ);
  137.     else
  138.         fp->bufsize = 0;
  139.     if (!fp->bufsize)
  140.     {
  141.         fp->flags |= __FL_EOF;
  142.     }
  143.     else if (fp->bufsize == -1)
  144.     {
  145.         fp->bufsize= 0;
  146.         fp->flags |= __FL_ERROR;
  147.         fp->readsize = 0;
  148.     }
  149.     else
  150.     {
  151.         fp->flags &= ~(__FL_ERROR | __FL_EOF);
  152.         fp->readsize = fp->bufsize;
  153.     }
  154.     fp->bufidx = 0;
  155.     return fp->bufsize;
  156. }
  157.  
  158. FILE    *fopen(char const *name, char const *mode)
  159. {
  160.     int    fd;
  161.     FILE    *fp;
  162.     int    modes;
  163.     int    flags;
  164.  
  165.     modes = getmodes(mode, &flags);
  166.  
  167.     fd = open(name, modes, 0666);
  168.  
  169.     if (fd == -1)
  170.         return 0;
  171.  
  172.     return fdopen(fd, mode);
  173. }
  174.  
  175. FILE    *fdopen(int fd, char const *mode)
  176. {
  177.     int    modes;
  178.     FILE    *fp;
  179.     int    flags;
  180.  
  181.     modes = getmodes(mode, &flags);
  182.     fp = &_iob[fd];
  183.     fp->fd = fd;
  184.     fp->modes = modes;
  185.     fp->flags = flags;
  186.     if (fp->buffer)
  187.     {
  188.         free(fp->buffer);
  189.         fp->buffer = 0;
  190.         fp->bufsize = 0;
  191.         fp->bufidx = 0;
  192.     }
  193.     if (!isatty(fd))
  194.     {
  195.         fp->buffer = (char *) malloc(BUFSIZ);
  196.         fp->bufsize = BUFSIZ;
  197.         fp->bufidx = BUFSIZ;
  198.         _filbuf(fp);
  199.     }
  200.  
  201.     return fp;
  202. }
  203.  
  204.  
  205. int    fclose(FILE *fp)
  206. {
  207.     _flsbuf(fp);
  208.     close(fp->fd);
  209.     if (fp->buffer)
  210.     {
  211.         free(fp->buffer);
  212.         fp->bufsize = 0;
  213.         fp->bufidx = 0;
  214.         fp->buffer = 0;
  215.     }
  216.     fp->fd = -1;
  217.     fp->flags = 0;
  218.     fp->modes = 0;
  219.     return 0;
  220. }
  221.  
  222. void    _init_all_files(void)
  223. {
  224.     int    i;
  225.  
  226.     for (i = 0; i < MAXFILES; i++)
  227.         _iob[i].fd = -1;
  228. }
  229.  
  230. void    _close_all_files(void)
  231. {
  232.     int    fd;
  233.  
  234.     for (fd = 0; fd < MAXFILES; fd++)
  235.     {
  236.         if (_iob[fd].fd != -1)
  237.         {
  238.             fclose(&_iob[fd]);
  239.         }
  240.     }
  241. }
  242.  
  243. FILE    *freopen(char const *file, char const *mode, FILE *fp)
  244. {
  245.     FILE    *fpNew;
  246.  
  247.     if (fp->fd)
  248.         fclose(fp);
  249.     fpNew = fopen(file, mode);
  250.     if (fp == fpNew)
  251.         return fp;
  252.     dup2(fpNew->fd, fp - _iob);
  253.     fclose(fpNew);
  254.     return fdopen(fp - _iob, mode);
  255. }
  256.  
  257.  
  258.  
  259. int    ungetc(char c, FILE *fp)
  260. {
  261.     if (fp->flags & __FL_UNGET)
  262.         return EOF;
  263.     fp->flags |= __FL_UNGET;
  264.     fp->ungetchar = c;
  265.     return 0;
  266. }
  267.  
  268. int    getc(FILE *fp)
  269. {
  270.     char    c;
  271.  
  272.     if (fp->flags & __FL_UNGET)
  273.     {
  274.         fp->flags &= ~__FL_UNGET;
  275.         return fp->ungetchar;
  276.     }
  277.     else if (fp->buffer)
  278.     {
  279.         if (fp->bufidx < fp->bufsize)
  280.             return (fp->buffer[fp->bufidx++]);
  281.         else if (_filbuf(fp))
  282.             return fp->buffer[fp->bufidx++];
  283.         else
  284.             return EOF;
  285.     }
  286.     else if (read(fp->fd, &c, 1) == 1)
  287.         return c;
  288.     else
  289.         return EOF;
  290. }
  291.  
  292. int    putc(char c, FILE *fp)
  293. {
  294.     if (fp->buffer)
  295.     {
  296.         if (fp->bufidx < BUFSIZ)
  297.         {
  298.             fp->buffer[fp->bufidx++] = c;
  299.             if (fp->bufidx > fp->bufsize)
  300.                 fp->bufsize = fp->bufidx;
  301.         }
  302.         else
  303.         {
  304.             _filbuf(fp);
  305.             fp->buffer[fp->bufidx++] = c;
  306.         }
  307.         fp->flags |= __FL_MODIFIED;
  308.         return c;
  309.     }
  310.     else
  311.     {
  312.         if (write(fp->fd, &c, 1) == 1)
  313.             return c;
  314.         else
  315.             return EOF;
  316.     }
  317. }
  318.  
  319. int    fscanf(FILE *fp, char const *format, ...)
  320. {
  321.     va_list    args;
  322.     int    retval;
  323.  
  324.     va_start(args, format);
  325.     retval = vfscanf(fp, format, args);
  326.     va_end(args);
  327.     return retval;
  328. }
  329. int    scanf(char const *format, ...)
  330. {
  331.     va_list    args;
  332.     int    retval;
  333.  
  334.     va_start(args, format);
  335.     retval = vfscanf(stdin, format, args);
  336.     va_end(args);
  337.     return retval;
  338. }
  339.  
  340. int    fp_fmtout(void *pv, char c)
  341. {
  342.     FILE *fp = (FILE *) pv;
  343.  
  344.     putc(c, fp);
  345.     return 1;
  346. }
  347.  
  348. int    vfprintf(FILE *fp, char const *format, va_list arg)
  349. {
  350.     return __formatter(fp_fmtout, fp, format, arg);
  351. }
  352.  
  353. int    fprintf(FILE *fp, char const *format, ...)
  354. {
  355.     va_list    args;
  356.     int    retval;
  357.  
  358.     va_start(args, format);
  359.     retval = vfprintf(fp, format, args);
  360.     va_end(args);
  361.     return retval;
  362. }
  363.  
  364. int    printf(char const *format, ...)
  365. {
  366.     va_list    args;
  367.     int    retval;
  368.  
  369.     va_start(args, format);
  370.     retval = vfprintf(stdout, format, args);
  371.     va_end(args);
  372.     return retval;
  373. }
  374.  
  375. int    puts(char const *pch)
  376. {
  377.     while (*pch)
  378.         if (putchar(*pch) == EOF)
  379.             return EOF;
  380.         else
  381.             pch++;
  382.     if (putchar('\n') == EOF)
  383.         return EOF;
  384.     return 0;
  385. }
  386.  
  387. char    *gets(char *pch)
  388. {
  389.     char    c;
  390.     char    *pchOut = pch;
  391.  
  392.     while (1)
  393.     {
  394.         c = getchar();
  395.         if (c == EOF)
  396.             return 0;
  397.         if (c == '\n')
  398.         {
  399.             *pchOut = '\0';
  400.             return pch;
  401.         }
  402.         *pchOut++ = c;
  403.     }
  404. }
  405.  
  406. int    fputs(char const *pch, FILE *fp)
  407. {
  408.     while (*pch)
  409.         if (putc(*pch, fp) == EOF)
  410.             return EOF;
  411.         else
  412.             pch++;
  413.     return 0;
  414. }
  415.  
  416. char    *fgets(char *pch, int nMax, FILE *fp)
  417. {
  418.     char    c;
  419.     char    *pchOut = pch;
  420.  
  421.     while (--nMax)
  422.     {
  423.         c = getc(fp);
  424.         if (c == EOF)
  425.             return 0;
  426.         *pchOut++ = c;
  427.         if (c == '\n')
  428.             break;
  429.     }
  430.     *pchOut = '\0';
  431.     return pch;
  432. }
  433.  
  434.  
  435. int
  436. fread(    char    *pchBuffer,
  437.     int    nSize,
  438.     int    nCount,
  439.     FILE    *fp)
  440. {
  441.     int    nRead = 0;
  442.     int    nReadSize = nSize * nCount;
  443.     int    nNow;
  444.  
  445.     if (nReadSize == 0)
  446.         return 0;
  447.     if (fp->flags & __FL_UNGET)
  448.     {
  449.         fp->flags &= ~__FL_UNGET;
  450.         *pchBuffer++ = fp->ungetchar;
  451.         nRead++;
  452.     }
  453.     if (fp->buffer)
  454.     {
  455.         while (nRead < nReadSize)
  456.         {
  457.             if (nReadSize - nRead < fp->bufsize - fp->bufidx)
  458.                 nNow = nReadSize - nRead;
  459.             else
  460.                 nNow = fp->bufsize - fp->bufidx;
  461.  
  462.             if (nNow)
  463.             {
  464.                 memcpy(pchBuffer, fp->buffer + fp->bufidx, nNow);
  465.                 fp->bufidx += nNow;
  466.                 pchBuffer += nNow;
  467.                 nRead += nNow;
  468.             }
  469.             else if (!_filbuf(fp))
  470.             {
  471.                 return nRead / nSize;
  472.             }
  473.         }
  474.         return nCount;
  475.     }
  476.     else
  477.     {
  478.         nRead = read(fp->fd, pchBuffer, nReadSize);
  479.         if (nRead <= -1)
  480.             return EOF;
  481.         return nRead / nSize;
  482.     }
  483. }
  484.  
  485. int
  486. fwrite(    char    const *pchBuffer,
  487.     int    nSize,
  488.     int    nCount,
  489.     FILE    *fp)
  490. {
  491.     int    nWritten = 0;
  492.     int    nToWrite = nSize * nCount;
  493.     int    nNow;
  494.  
  495.     if (fp->buffer)
  496.     {
  497.         while (nWritten < nToWrite)
  498.         {
  499.             if (BUFSIZ - fp->bufidx < nToWrite - nWritten)
  500.                 nNow = BUFSIZ - fp->bufidx;
  501.             else
  502.                 nNow = nToWrite - nWritten;
  503.             if (nNow)
  504.             {
  505.                 memcpy(fp->buffer + fp->bufidx, pchBuffer, nNow);
  506.                 pchBuffer += nNow;
  507.                 fp->bufidx += nNow;
  508.                 nWritten += nNow;
  509.                 if (fp->bufidx > fp->bufsize)
  510.                     fp->bufsize = fp->bufidx;
  511.                 fp->flags |= __FL_MODIFIED;
  512.             }
  513.             else
  514.             {
  515.                 _filbuf(fp);
  516.             }
  517.         }
  518.         return nWritten / nCount;
  519.     }
  520.     else
  521.     {
  522.         nWritten = write(fp->fd, (void *) pchBuffer, nToWrite);
  523.         if (nWritten < 0)
  524.             return EOF;
  525.         return nWritten / nSize;
  526.     }
  527. }
  528.